# Date
import ee 
import geemap

ee_date = ee.Date.fromYMD(year,month,day)

# create month list by map
# -----------------------------------------------------------------------------
# get years
# not include the end year
const = {
    "start_year":2000,
    "end_year":2021,
}
vYears = [*range(const["start_year"],const["end_year"],1)]
ee_years = ee.List(vYears)
# get months
def get_months(nYear):
    vMonths = [*range(1,13,1)]
    ee_months = ee.List(vMonths)
    return ee_months.map(lambda x: ee.Date.fromYMD(nYear,x,1))
# get months in all years
ee_years.map(get_months).flatten()


# create day list by map
# -----------------------------------------------------------------------------
# end_date not included
const = {
    "start_date":"2016-01-01",
    "end_date":"2020-01-01",
}

ee_end_day = ee.Date(const["end_date"])
ee_start_day = ee.Date(const["start_date"])
# get the number of days in this period
ee_n_days = ee_end_day.difference(ee_start_day,"day")
ee_delta_day =  ee.List.sequence(0,ee_n_days.add(ee.Number(-1)))

# get the head of each date, return as list
def get_head_day(nn):
    return ee.Date(ee_start_day).advance(nn,"day")
ee_head_day = ee_delta_day.map(get_head_day)


## FeatureCollections
# ------------------------------------------------------------------------------

# convert csv of points to featureCollection
path_csv = r"path/to/csv/file"
# change the column names for Latitude and Longitude
# convert csv to FeatureCollection
ee_points = geemap.csv_to_ee(path_csv, latitude = "Latitude", longitude = "Longitude")

# extract values as featureCollection (Points)
imgCols = ee.ImageCollection("some collection")
path_out = r"path/to/save/results"
geemap.extract_values_to_points(ee_points,imgCols,path_out)

# extract values on different images (location and time) as featureCollections
def get_properties_per_point(point):
    # set the imageCollections for value extracting
    subCols = colsLandsat
    
    # get the date and date range for filtering
    ee_date = ee.Date(point.get("Date"))
    ee_date_head = ee_date.advance(-16,unit = "day")
    ee_date_tail = ee_date.advance(16,unit = "day")
    
    # find the image for this point
    subCols = subCols.filterBounds(point.geometry()) \
        .filterDate(ee_date_head, ee_date_tail)
    
    # get the image for extracting values
    dateOfInterest = ee_date
    # sub function to find the nearest image
    def find_nearest_date_image(Cols,dateOfInterest):
        dateOfInterest = ee.Date(dateOfInterest)
        def set_image_dist(image):
            image.set(
                'dateDist',
                ee.Number(image.get('system:time_start')).subtract(dateOfInterest.millis()).abs)
            return image
        return Cols.map(set_image_dist).sort("dateDist").first()
    # do the work
    img = find_nearest_date_image(subCols, ee_date)
    
    # extract values
    # geemap.extract_values_to_points don't work with one feature collection.
    # so we use geemap.extract_pixel_values to extract band value from images
    values = geemap.extract_pixel_values(img, point.geometry(),scale = 30)
    return point.set(values)


# convert FeatureCollection to csv and save to disk